package com.crowntit.trigger.http;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.crowntit.api.IPayService;
import com.crowntit.api.dto.CreateOrderDTO;
import com.crowntit.api.dto.NotifyRequestDTO;
import com.crowntit.api.response.Response;
import com.crowntit.domain.order.model.entity.GroupBuyNotifyEntity;
import com.crowntit.domain.order.model.entity.OrderPaySuccessEntity;
import com.crowntit.domain.order.model.entity.PayOrderEntity;
import com.crowntit.domain.order.model.entity.ShopCartEntity;
import com.crowntit.domain.order.service.IOrderService;
import com.crowntit.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController()
@CrossOrigin("*")
@RequestMapping("/api/v1/alipay/")
public class PayController implements IPayService {

    @Value("${alipay.alipay_public_key}")
    private String alipayPublicKey;
    @Value("${default-product.product-id}")
    private String defaultProductId;

    @Resource
    private IOrderService orderService;

    @Override
    @RequestMapping(value = "create_pay_order", method = RequestMethod.POST)
    public Response<String> createOrder(@RequestBody CreateOrderDTO createOrderDTO) {
        try {
            String userId = createOrderDTO.getUserId();
            String productId = createOrderDTO.getProductId();
//            String productId = defaultProductId;
            Long activityId = createOrderDTO.getActivityId();
            String teamId = createOrderDTO.getTeamId();

            if (StringUtils.isBlank(userId) || StringUtils.isBlank(createOrderDTO.getProductId())) {
                log.error("商品下单-参数为空: 入参: {}", JSON.toJSONString(createOrderDTO));
                return Response.<String>builder()
                        .code(Constants.ResponseCode.PARAMETER_ERROR.getCode())
                        .message(Constants.ResponseCode.PARAMETER_ERROR.getInfo())
                        .data(null)
                        .build();
            }

            if (createOrderDTO.isGroupBuy()) {
                if (activityId == null) {
                    log.error("商品下单-参数为空: 入参: #{}", JSON.toJSONString(createOrderDTO));
                    return Response.<String>builder()
                            .code(Constants.ResponseCode.PARAMETER_ERROR.getCode())
                            .message(Constants.ResponseCode.PARAMETER_ERROR.getInfo())
                            .data(null)
                            .build();
                }
            }

            log.info("商品下单-入参: {}", JSON.toJSONString(createOrderDTO));

            ShopCartEntity shopCartReq = ShopCartEntity.builder()
                    .isGroupBuy(createOrderDTO.isGroupBuy())
                    .productId(productId)
                    .userId(userId)
                    .build();
            if (createOrderDTO.isGroupBuy()) {
                shopCartReq.setActivityId(activityId);
                shopCartReq.setTeamId(teamId);
            }

            PayOrderEntity payOrder = orderService.createOrder(shopCartReq);
            log.info("商品下单，根据商品ID创建支付单完成 userId:{} productId:{} orderId:{}", userId, productId, payOrder.getOrderId());

            return Response.<String>builder()
                    .code(Constants.ResponseCode.SUCCESS.getCode())
                    .message(Constants.ResponseCode.SUCCESS.getInfo())
                    .data(payOrder.getPayUrl())
                    .build();
        } catch (Exception e) {
            log.error("商品下单，根据商品ID创建支付单失败 userId:{} productId:{}", createOrderDTO.getUserId(), createOrderDTO.getUserId(), e);
            return Response.<String>builder()
                    .code(Constants.ResponseCode.ERROR.getCode())
                    .message(Constants.ResponseCode.ERROR.getInfo())
                    .build();
        }
    }

    @RequestMapping(value = "alipay_notify_url", method = RequestMethod.POST)
    public String payNotify(HttpServletRequest request) throws AlipayApiException, IOException {
        log.info("支付回调，消息接收 {}", request.getParameter("trade_status"));

        // 如果状态是TRADE_SUCCESS / TRADE_FINISHED 才是支付成功
        if (!request.getParameter("trade_status").equals("TRADE_SUCCESS")){
            return "false";
        }

        // 1. 验签
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (String name : requestParams.keySet()){
            params.put(name, request.getParameter(name));
        }

        String tradeNo = params.get("out_trade_no");
        String gmtPayment = params.get("gmt_payment");
        String alipayTradeNo = params.get("trade_no");

        String sign = params.get("sign");
        String content = AlipaySignature.getSignCheckContentV1(params);
        boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, alipayPublicKey, "UTF-8");

        if (!checkSignature){
            return "false";
        }

        // 验签通过
        log.info("支付回调，交易名称: {}", params.get("subject"));
        log.info("支付回调，交易状态: {}", params.get("trade_status"));
        log.info("支付回调，支付宝交易凭证号: {}", params.get("trade_no"));
        log.info("支付回调，商户订单号: {}", params.get("out_trade_no"));
        log.info("支付回调，交易金额: {}", params.get("total_amount"));
        log.info("支付回调，买家在支付宝唯一id: {}", params.get("buyer_id"));
        log.info("支付回调，买家付款时间: {}", params.get("gmt_payment"));
        log.info("支付回调，买家付款金额: {}", params.get("buyer_pay_amount"));
        log.info("支付回调，支付回调，更新订单 {}", tradeNo);

        // 2. 更新订单状态
        orderService.changeOrderPaySuccess(tradeNo);
        return "success";
    }

    /**
     * 接收团购服务的拼团组队状态回调
     * @param requestDTO
     * @return
     */
    @RequestMapping(value = "group_buy_notify", method = RequestMethod.POST)
    @Override
    public String groupBuyNotify(@RequestBody NotifyRequestDTO requestDTO) {
        log.info("团购回调-接收到团购系统的拼团组队回调信息");
        log.info("团购回调-入参: {}", JSON.toJSONString(requestDTO));

        // 接收回调信息
        String teamId = requestDTO.getTeamId();
        List<String> outTradeNoList = requestDTO.getOutTradeNoList();
        String groupBuyTeamStatus = requestDTO.getStatus();

        // 参数判断
        if (outTradeNoList == null || outTradeNoList.isEmpty() || StringUtils.isBlank(groupBuyTeamStatus)) {
            log.info("团购回调-请求参数为空");
            return "fail";
        }

        try {
            orderService.changeOrderGroupBuyTeamStatus(GroupBuyNotifyEntity.builder()
                    .gbmOutTradeNoList(outTradeNoList)
                    .groupBuyTeamStatus(groupBuyTeamStatus)
                    .build());
        } catch (Exception e) {
            log.info("团购回调-修改系统内订单状态时发生错误");
            return "fail";
        }
        return "success";
    }
}
